home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 60 / IOPROG_60.ISO / soft / c++ / gsl-1.1.1-setup.exe / {app} / src / specfunc / legendre_con.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-04-18  |  42.9 KB  |  1,374 lines

  1. /* specfunc/legendre_con.c
  2.  * 
  3.  * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
  4.  * 
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or (at
  8.  * your option) any later version.
  9.  * 
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. /* Author:  G. Jungman */
  21.  
  22. #include <config.h>
  23. #include <gsl/gsl_math.h>
  24. #include <gsl/gsl_errno.h>
  25. #include <gsl/gsl_poly.h>
  26. #include <gsl/gsl_sf_exp.h>
  27. #include <gsl/gsl_sf_trig.h>
  28. #include <gsl/gsl_sf_gamma.h>
  29. #include <gsl/gsl_sf_ellint.h>
  30. #include <gsl/gsl_sf_pow_int.h>
  31. #include <gsl/gsl_sf_bessel.h>
  32. #include <gsl/gsl_sf_hyperg.h>
  33. #include <gsl/gsl_sf_legendre.h>
  34.  
  35. #include "error.h"
  36. #include "legendre.h"
  37.  
  38. #define Root_2OverPi_  0.797884560802865355879892
  39. #define locEPS         (1000.0*GSL_DBL_EPSILON)
  40.  
  41.  
  42. /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/
  43.  
  44.  
  45. #define RECURSE_LARGE  (1.0e-5*GSL_DBL_MAX)
  46. #define RECURSE_SMALL  (1.0e+5*GSL_DBL_MIN)
  47.  
  48.  
  49. /* Continued fraction for f_{ell+1}/f_ell
  50.  * f_ell := P^{-mu-ell}_{-1/2 + I tau}(x),  x < 1.0
  51.  *
  52.  * Uses standard CF method from Temme's book.
  53.  */
  54. static
  55. int
  56. conicalP_negmu_xlt1_CF1(const double mu, const int ell, const double tau,
  57.                         const double x, gsl_sf_result * result)
  58. {
  59.   const double RECUR_BIG = GSL_SQRT_DBL_MAX;
  60.   const int maxiter = 5000;
  61.   int n = 1;
  62.   double xi = x/(sqrt(1.0-x)*sqrt(1.0+x));
  63.   double Anm2 = 1.0;
  64.   double Bnm2 = 0.0;
  65.   double Anm1 = 0.0;
  66.   double Bnm1 = 1.0;
  67.   double a1 = 1.0;
  68.   double b1 = 2.0*(mu + ell + 1.0) * xi;
  69.   double An = b1*Anm1 + a1*Anm2;
  70.   double Bn = b1*Bnm1 + a1*Bnm2;
  71.   double an, bn;
  72.   double fn = An/Bn;
  73.  
  74.   while(n < maxiter) {
  75.     double old_fn;
  76.     double del;
  77.     n++;
  78.     Anm2 = Anm1;
  79.     Bnm2 = Bnm1;
  80.     Anm1 = An;
  81.     Bnm1 = Bn;
  82.     an = tau*tau + (mu - 0.5 + ell + n)*(mu - 0.5 + ell + n);
  83.     bn = 2.0*(ell + mu + n) * xi;
  84.     An = bn*Anm1 + an*Anm2;
  85.     Bn = bn*Bnm1 + an*Bnm2;
  86.  
  87.     if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) {
  88.       An /= RECUR_BIG;
  89.       Bn /= RECUR_BIG;
  90.       Anm1 /= RECUR_BIG;
  91.       Bnm1 /= RECUR_BIG;
  92.       Anm2 /= RECUR_BIG;
  93.       Bnm2 /= RECUR_BIG;
  94.     }
  95.  
  96.     old_fn = fn;
  97.     fn = An/Bn;
  98.     del = old_fn/fn;
  99.     
  100.     if(fabs(del - 1.0) < 2.0*GSL_DBL_EPSILON) break;
  101.   }
  102.  
  103.   result->val = fn;
  104.   result->err = 4.0 * GSL_DBL_EPSILON * (sqrt(n) + 1.0) * fabs(fn);
  105.  
  106.   if(n >= maxiter)
  107.     GSL_ERROR ("error", GSL_EMAXITER);
  108.   else
  109.     return GSL_SUCCESS;
  110. }
  111.  
  112.  
  113. /* Continued fraction for f_{ell+1}/f_ell
  114.  * f_ell := P^{-mu-ell}_{-1/2 + I tau}(x),  x >= 1.0
  115.  *
  116.  * Uses Gautschi (Euler) equivalent series.
  117.  */
  118. static
  119. int
  120. conicalP_negmu_xgt1_CF1(const double mu, const int ell, const double tau,
  121.                         const double x, gsl_sf_result * result)
  122.   const int maxk = 20000;
  123.   const double gamma = 1.0-1.0/(x*x);
  124.   const double pre = sqrt(x-1.0)*sqrt(x+1.0) / (x*(2.0*(ell+mu+1.0)));
  125.   double tk   = 1.0;
  126.   double sum  = 1.0;
  127.   double rhok = 0.0;
  128.   int k;
  129.  
  130.   for(k=1; k<maxk; k++) {
  131.     double tlk = 2.0*(ell + mu + k);
  132.     double l1k = (ell + mu - 0.5 + 1.0 + k);
  133.     double ak = -(tau*tau + l1k*l1k)/(tlk*(tlk+2.0)) * gamma;
  134.     rhok = -ak*(1.0 + rhok)/(1.0 + ak*(1.0 + rhok));
  135.     tk  *= rhok;
  136.     sum += tk;
  137.     if(fabs(tk/sum) < GSL_DBL_EPSILON) break;
  138.   }
  139.  
  140.   result->val  = pre * sum;
  141.   result->err  = fabs(pre * tk);
  142.   result->err += 2.0 * GSL_DBL_EPSILON * (sqrt(k) + 1.0) * fabs(pre*sum);
  143.  
  144.   if(k >= maxk)
  145.     GSL_ERROR ("error", GSL_EMAXITER);
  146.   else
  147.     return GSL_SUCCESS;
  148. }
  149.  
  150.  
  151. /* Implementation of large negative mu asymptotic
  152.  * [Dunster, Proc. Roy. Soc. Edinburgh 119A, 311 (1991), p. 326]
  153.  */
  154.  
  155. inline
  156. static double olver_U1(double beta2, double p)
  157. {
  158.   return (p-1.0)/(24.0*(1.0+beta2)) * (3.0 + beta2*(2.0 + 5.0*p*(1.0+p)));
  159. }
  160.  
  161. inline
  162. static double olver_U2(double beta2, double p)
  163. {
  164.   double beta4 = beta2*beta2;
  165.   double p2    = p*p;
  166.   double poly1 =  4.0*beta4 + 84.0*beta2 - 63.0;
  167.   double poly2 = 16.0*beta4 + 90.0*beta2 - 81.0;
  168.   double poly3 = beta2*p2*(97.0*beta2 - 432.0 + 77.0*p*(beta2-6.0) - 385.0*beta2*p2*(1.0 + p));
  169.   return (1.0-p)/(1152.0*(1.0+beta2)) * (poly1 + poly2 + poly3);
  170. }
  171.  
  172. static const double U3c1[] = {   -1307.0,   -1647.0,    3375.0,    3675.0 };
  173. static const double U3c2[] = {   29366.0,   35835.0, -252360.0, -272630.0,
  174.                                 276810.0,  290499.0 };
  175. static const double U3c3[] = {  -29748.0,   -8840.0, 1725295.0, 1767025.0,
  176.                               -7313470.0, -754778.0, 6309875.0, 6480045.0 };
  177. static const double U3c4[] = {    2696.0,    -16740.0,   -524250.0,  -183975.0,
  178.                               14670540.0,  14172939.0, -48206730.0, -48461985.0,
  179.                   36756720.0,  37182145.0 };
  180. static const double U3c5[] = {       9136.0,      22480.0,     12760.0,
  181.                                   -252480.0,   -4662165.0,   -1705341.0,
  182.                  92370135.0,   86244015.0, -263678415.0,
  183.                    -260275015.0, 185910725.0,  185910725.0 };
  184.  
  185. #if 0
  186. static double olver_U3(double beta2, double p)
  187. {
  188.   double beta4 = beta2*beta2;
  189.   double beta6 = beta4*beta2;
  190.   double opb2s = (1.0+beta2)*(1.0+beta2);
  191.   double den   = 39813120.0 * opb2s*opb2s;
  192.   double poly1 = gsl_poly_eval(U3c1, 4, p);
  193.   double poly2 = gsl_poly_eval(U3c2, 6, p);
  194.   double poly3 = gsl_poly_eval(U3c3, 8, p);
  195.   double poly4 = gsl_poly_eval(U3c4, 10, p);
  196.   double poly5 = gsl_poly_eval(U3c5, 12, p);
  197.   
  198.   return (p-1.0)*(     1215.0*poly1 + 324.0*beta2*poly2
  199.                  + 54.0*beta4*poly3 +  12.0*beta6*poly4
  200.          + beta4*beta4*poly5
  201.          ) / den;
  202. }
  203. #endif /* 0 */
  204.  
  205.  
  206. /* Large negative mu asymptotic
  207.  * P^{-mu}_{-1/2 + I tau}, mu -> Inf
  208.  * |x| < 1
  209.  *
  210.  * [Dunster, Proc. Roy. Soc. Edinburgh 119A, 311 (1991), p. 326]
  211.  */
  212. int
  213. gsl_sf_conicalP_xlt1_large_neg_mu_e(double mu, double tau, double x,
  214.                                        gsl_sf_result * result, double * ln_multiplier)
  215. {
  216.   double beta  = tau/mu;
  217.   double beta2 = beta*beta;
  218.   double S     = beta * acos((1.0-beta2)/(1.0+beta2));
  219.   double p     = x/sqrt(beta2*(1.0-x*x) + 1.0);
  220.   gsl_sf_result lg_mup1;
  221.   int lg_stat = gsl_sf_lngamma_e(mu+1.0, &lg_mup1);
  222.   double ln_pre_1 =  0.5*mu*(S - log(1.0+beta2) + log((1.0-p)/(1.0+p))) - lg_mup1.val;
  223.   double ln_pre_2 = -0.25 * log(1.0 + beta2*(1.0-x));
  224.   double ln_pre_3 = -tau * atan(p*beta);
  225.   double ln_pre = ln_pre_1 + ln_pre_2 + ln_pre_3;
  226.   double sum   = 1.0 - olver_U1(beta2, p)/mu + olver_U2(beta2, p)/(mu*mu);
  227.  
  228.   if(sum == 0.0) {
  229.     result->val = 0.0;
  230.     result->err = 0.0;
  231.     *ln_multiplier = 0.0;
  232.     return GSL_SUCCESS;
  233.   }
  234.   else {
  235.     int stat_e = gsl_sf_exp_mult_e(ln_pre, sum, result);
  236.     if(stat_e != GSL_SUCCESS) {
  237.       result->val = sum;
  238.       result->err = 2.0 * GSL_DBL_EPSILON * fabs(sum);
  239.       *ln_multiplier = ln_pre;
  240.     }
  241.     else {
  242.       *ln_multiplier = 0.0;
  243.     }
  244.     return lg_stat;
  245.   }
  246. }
  247.  
  248.  
  249. /* Implementation of large tau asymptotic
  250.  *
  251.  * A_n^{-mu}, B_n^{-mu}  [Olver, p.465, 469]
  252.  */
  253.  
  254. inline
  255. static double olver_B0_xi(double mu, double xi)
  256. {
  257.   return (1.0 - 4.0*mu*mu)/(8.0*xi) * (1.0/tanh(xi) - 1.0/xi);
  258. }
  259.  
  260. static double olver_A1_xi(double mu, double xi, double x)
  261. {
  262.   double B = olver_B0_xi(mu, xi);
  263.   double psi;
  264.   if(fabs(x - 1.0) < GSL_ROOT4_DBL_EPSILON) {
  265.     double y = x - 1.0;
  266.     double s = -1.0/3.0 + y*(2.0/15.0 - y *(61.0/945.0 - 452.0/14175.0*y));
  267.     psi = (4.0*mu*mu - 1.0)/16.0 * s;
  268.   }
  269.   else {
  270.     psi = (4.0*mu*mu - 1.0)/16.0 * (1.0/(x*x-1.0) - 1.0/(xi*xi));
  271.   }
  272.   return 0.5*xi*xi*B*B + (mu+0.5)*B - psi + mu/6.0*(0.25 - mu*mu);
  273. }
  274.  
  275. inline
  276. static double olver_B0_th(double mu, double theta)
  277. {
  278.   return -(1.0 - 4.0*mu*mu)/(8.0*theta) * (1.0/tan(theta) - 1.0/theta);
  279. }
  280.  
  281. static double olver_A1_th(double mu, double theta, double x)
  282. {
  283.   double B = olver_B0_th(mu, theta);
  284.   double psi;
  285.   if(fabs(x - 1.0) < GSL_ROOT4_DBL_EPSILON) {
  286.     double y = 1.0 - x;
  287.     double s = -1.0/3.0 + y*(2.0/15.0 - y *(61.0/945.0 - 452.0/14175.0*y));
  288.     psi = (4.0*mu*mu - 1.0)/16.0 * s;
  289.   }
  290.   else {
  291.     psi = (4.0*mu*mu - 1.0)/16.0 * (1.0/(x*x-1.0) + 1.0/(theta*theta));
  292.   }
  293.   return -0.5*theta*theta*B*B + (mu+0.5)*B - psi + mu/6.0*(0.25 - mu*mu);
  294. }
  295.  
  296.  
  297. /* Large tau uniform asymptotics
  298.  * P^{-mu}_{-1/2 + I tau}
  299.  * 1 < x
  300.  * tau -> Inf 
  301.  * [Olver, p. 469]
  302.  */
  303. int
  304. gsl_sf_conicalP_xgt1_neg_mu_largetau_e(const double mu, const double tau,
  305.                                           const double x, double acosh_x,
  306.                                           gsl_sf_result * result, double * ln_multiplier)
  307. {
  308.   double xi = acosh_x;
  309.   double ln_xi_pre;
  310.   double ln_pre;
  311.   double sumA, sumB, sum;
  312.   double arg;
  313.   gsl_sf_result J_mup1;
  314.   gsl_sf_result J_mu;
  315.   double J_mum1;
  316.  
  317.   if(xi < GSL_ROOT4_DBL_EPSILON) {
  318.     ln_xi_pre = -xi*xi/6.0;           /* log(1.0 - xi*xi/6.0) */
  319.   }
  320.   else {
  321.     gsl_sf_result lnshxi;
  322.     gsl_sf_lnsinh_e(xi, &lnshxi);
  323.     ln_xi_pre = log(xi) - lnshxi.val;     /* log(xi/sinh(xi) */
  324.   }
  325.  
  326.   ln_pre = 0.5*ln_xi_pre - mu*log(tau);
  327.  
  328.   arg = tau*xi;
  329.  
  330.   gsl_sf_bessel_Jnu_e(mu + 1.0,   arg, &J_mup1);
  331.   gsl_sf_bessel_Jnu_e(mu,         arg, &J_mu);
  332.   J_mum1 = -J_mup1.val + 2.0*mu/arg*J_mu.val;      /* careful of mu < 1 */
  333.  
  334.   sumA = 1.0 - olver_A1_xi(-mu, xi, x)/(tau*tau);
  335.   sumB = olver_B0_xi(-mu, xi);
  336.   sum  = J_mu.val * sumA - xi/tau * J_mum1 * sumB;
  337.  
  338.   if(sum == 0.0) {
  339.     result->val = 0.0;
  340.     result->err = 0.0;
  341.     *ln_multiplier = 0.0;
  342.     return GSL_SUCCESS;
  343.   }
  344.   else {
  345.     int stat_e = gsl_sf_exp_mult_e(ln_pre, sum, result);
  346.     if(stat_e != GSL_SUCCESS) {
  347.       result->val = sum;
  348.       result->err = 2.0 * GSL_DBL_EPSILON * fabs(sum);
  349.       *ln_multiplier = ln_pre;
  350.     }
  351.     else {
  352.       *ln_multiplier = 0.0;
  353.     }
  354.     return GSL_SUCCESS;
  355.   }
  356. }
  357.  
  358.  
  359. /* Large tau uniform asymptotics
  360.  * P^{-mu}_{-1/2 + I tau}
  361.  * -1 < x < 1
  362.  * tau -> Inf 
  363.  * [Olver, p. 473]
  364.  */
  365. int
  366. gsl_sf_conicalP_xlt1_neg_mu_largetau_e(const double mu, const double tau,
  367.                                           const double x, const double acos_x,
  368.                                           gsl_sf_result * result, double * ln_multiplier)
  369. {
  370.   double theta = acos_x;
  371.   double ln_th_pre;
  372.   double ln_pre;
  373.   double sumA, sumB, sum, sumerr;
  374.   double arg;
  375.   gsl_sf_result I_mup1, I_mu;
  376.   double I_mum1;
  377.  
  378.   if(theta < GSL_ROOT4_DBL_EPSILON) {
  379.     ln_th_pre = theta*theta/6.0;   /* log(1.0 + theta*theta/6.0) */
  380.   }
  381.   else {
  382.     ln_th_pre = log(theta/sin(theta));
  383.   }
  384.  
  385.   ln_pre = 0.5 * ln_th_pre - mu * log(tau);
  386.  
  387.   arg = tau*theta;
  388.   gsl_sf_bessel_Inu_e(mu + 1.0,   arg, &I_mup1);
  389.   gsl_sf_bessel_Inu_e(mu,         arg, &I_mu);
  390.   I_mum1 = I_mup1.val + 2.0*mu/arg * I_mu.val; /* careful of mu < 1 */
  391.  
  392.   sumA = 1.0 - olver_A1_th(-mu, theta, x)/(tau*tau);
  393.   sumB = olver_B0_th(-mu, theta);
  394.   sum  = I_mu.val * sumA - theta/tau * I_mum1 * sumB;
  395.   sumerr  = fabs(I_mu.err * sumA);
  396.   sumerr += fabs(I_mup1.err * theta/tau * sumB);
  397.   sumerr += fabs(I_mu.err   * theta/tau * sumB * 2.0 * mu/arg);
  398.  
  399.   if(sum == 0.0) {
  400.     result->val = 0.0;
  401.     result->err = 0.0;
  402.     *ln_multiplier = 0.0;
  403.     return GSL_SUCCESS;
  404.   }
  405.   else {
  406.     int stat_e = gsl_sf_exp_mult_e(ln_pre, sum, result);
  407.     if(stat_e != GSL_SUCCESS) {
  408.       result->val  = sum;
  409.       result->err  = sumerr;
  410.       result->err += GSL_DBL_EPSILON * fabs(sum);
  411.       *ln_multiplier = ln_pre;
  412.     }
  413.     else {
  414.       *ln_multiplier = 0.0;
  415.     }
  416.     return GSL_SUCCESS;
  417.   }
  418. }
  419.  
  420.  
  421. /* Hypergeometric function which appears in the
  422.  * large x expansion below:
  423.  *
  424.  *   2F1(1/4 - mu/2 - I tau/2, 3/4 - mu/2 - I tau/2, 1 - I tau, y)
  425.  *
  426.  * Note that for the usage below y = 1/x^2;
  427.  */
  428. static
  429. int
  430. conicalP_hyperg_large_x(const double mu, const double tau, const double y,
  431.                         double * reF, double * imF)
  432. {
  433.   const int kmax = 1000;
  434.   const double re_a = 0.25 - 0.5*mu;
  435.   const double re_b = 0.75 - 0.5*mu;
  436.   const double re_c = 1.0;
  437.   const double im_a = -0.5*tau;
  438.   const double im_b = -0.5*tau;
  439.   const double im_c = -tau;
  440.  
  441.   double re_sum = 1.0;
  442.   double im_sum = 0.0;
  443.   double re_term = 1.0;
  444.   double im_term = 0.0;
  445.   int k;
  446.  
  447.   for(k=1; k<=kmax; k++) {
  448.     double re_ak = re_a + k - 1.0;
  449.     double re_bk = re_b + k - 1.0;
  450.     double re_ck = re_c + k - 1.0;
  451.     double im_ak = im_a;
  452.     double im_bk = im_b;
  453.     double im_ck = im_c;
  454.     double den = re_ck*re_ck + im_ck*im_ck;
  455.     double re_multiplier = ((re_ak*re_bk - im_ak*im_bk)*re_ck + im_ck*(im_ak*re_bk + re_ak*im_bk)) / den;
  456.     double im_multiplier = ((im_ak*re_bk + re_ak*im_bk)*re_ck - im_ck*(re_ak*re_bk - im_ak*im_bk)) / den;
  457.     double re_tmp = re_multiplier*re_term - im_multiplier*im_term;
  458.     double im_tmp = im_multiplier*re_term + re_multiplier*im_term;
  459.     double asum = fabs(re_sum) + fabs(im_sum);
  460.     re_term = y/k * re_tmp;
  461.     im_term = y/k * im_tmp;
  462.     if(fabs(re_term/asum) < GSL_DBL_EPSILON && fabs(im_term/asum) < GSL_DBL_EPSILON) break;
  463.     re_sum += re_term;
  464.     im_sum += im_term;
  465.   }
  466.  
  467.   *reF = re_sum;
  468.   *imF = im_sum;
  469.  
  470.   if(k == kmax)
  471.     GSL_ERROR ("error", GSL_EMAXITER);
  472.   else  
  473.     return GSL_SUCCESS;
  474. }
  475.  
  476.  
  477. /* P^{mu}_{-1/2 + I tau}
  478.  * x->Inf
  479.  */
  480. int
  481. gsl_sf_conicalP_large_x_e(const double mu, const double tau, const double x,
  482.                              gsl_sf_result * result, double * ln_multiplier)
  483. {
  484.   /* 2F1 term
  485.    */
  486.   double y = ( x < 0.5*GSL_SQRT_DBL_MAX ? 1.0/(x*x) : 0.0 );
  487.   double reF, imF;
  488.   int stat_F = conicalP_hyperg_large_x(mu, tau, y, &reF, &imF);
  489.  
  490.   /* f = Gamma(+i tau)/Gamma(1/2 - mu + i tau)
  491.    * FIXME: shift so it's better for tau-> 0
  492.    */
  493.   gsl_sf_result lgr_num, lgth_num;
  494.   gsl_sf_result lgr_den, lgth_den;
  495.   int stat_gn = gsl_sf_lngamma_complex_e(0.0,tau,&lgr_num,&lgth_num);
  496.   int stat_gd = gsl_sf_lngamma_complex_e(0.5-mu,tau,&lgr_den,&lgth_den);
  497.  
  498.   double angle = lgth_num.val - lgth_den.val + atan2(imF,reF);
  499.  
  500.   double lnx   = log(x);
  501.   double lnxp1 = log(x+1.0);
  502.   double lnxm1 = log(x-1.0);
  503.   double lnpre_const = 0.5*M_LN2 - 0.5*M_LNPI;
  504.   double lnpre_comm = (mu-0.5)*lnx - 0.5*mu*(lnxp1 + lnxm1);
  505.   double lnpre_err  =   GSL_DBL_EPSILON * (0.5*M_LN2 + 0.5*M_LNPI)
  506.                       + GSL_DBL_EPSILON * fabs((mu-0.5)*lnx)
  507.               + GSL_DBL_EPSILON * fabs(0.5*mu)*(fabs(lnxp1)+fabs(lnxm1));
  508.  
  509.   /*  result = pre*|F|*|f| * cos(angle - tau * (log(x)+M_LN2))
  510.    */
  511.   gsl_sf_result cos_result;
  512.   int stat_cos = gsl_sf_cos_e(angle + tau*(log(x) + M_LN2), &cos_result);
  513.   int status = GSL_ERROR_SELECT_4(stat_cos, stat_gd, stat_gn, stat_F);
  514.   if(cos_result.val == 0.0) {
  515.     result->val = 0.0;
  516.     result->err = 0.0;
  517.     return status;
  518.   }
  519.   else {
  520.     double lnFf_val = 0.5*log(reF*reF+imF*imF) + lgr_num.val - lgr_den.val;
  521.     double lnFf_err = lgr_num.err + lgr_den.err + GSL_DBL_EPSILON * fabs(lnFf_val);
  522.     double lnnoc_val = lnpre_const + lnpre_comm + lnFf_val;
  523.     double lnnoc_err = lnpre_err + lnFf_err + GSL_DBL_EPSILON * fabs(lnnoc_val);
  524.     int stat_e = gsl_sf_exp_mult_err_e(lnnoc_val, lnnoc_err,
  525.                                           cos_result.val, cos_result.err,
  526.                                           result);
  527.     if(stat_e == GSL_SUCCESS) {
  528.       *ln_multiplier = 0.0;
  529.     }
  530.     else {
  531.       result->val  = cos_result.val;
  532.       result->err  = cos_result.err;
  533.       result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  534.       *ln_multiplier = lnnoc_val;
  535.     }
  536.     return status;
  537.   }
  538. }
  539.  
  540.  
  541. /* P^{mu}_{-1/2 + I tau}  first hypergeometric representation
  542.  * -1 < x < 1
  543.  * This is more effective for |x| small, however it will work w/o
  544.  * reservation for any x < 0 because everything is positive
  545.  * definite in that case.
  546.  *
  547.  * [Kolbig,   (3)] (note typo in args of gamma functions)
  548.  * [Bateman, (22)] (correct form)
  549.  */
  550. static
  551. int
  552. conicalP_xlt1_hyperg_A(double mu, double tau, double x, gsl_sf_result * result)
  553. {
  554.   double x2 = x*x;
  555.   double err_amp = 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-fabs(x)));
  556.   double pre_val = M_SQRTPI / pow(0.5*sqrt(1-x2), mu);
  557.   double pre_err = err_amp * GSL_DBL_EPSILON * (fabs(mu)+1.0) * fabs(pre_val) ;
  558.   gsl_sf_result ln_g1, ln_g2, arg_g1, arg_g2;
  559.   gsl_sf_result F1, F2;
  560.   gsl_sf_result pre1, pre2;
  561.   double t1_val, t1_err;
  562.   double t2_val, t2_err;
  563.  
  564.   int stat_F1 = gsl_sf_hyperg_2F1_conj_e(0.25 - 0.5*mu, 0.5*tau, 0.5, x2, &F1);
  565.   int stat_F2 = gsl_sf_hyperg_2F1_conj_e(0.75 - 0.5*mu, 0.5*tau, 1.5, x2, &F2);
  566.   int status = GSL_ERROR_SELECT_2(stat_F1, stat_F2);
  567.  
  568.   gsl_sf_lngamma_complex_e(0.75 - 0.5*mu, -0.5*tau, &ln_g1, &arg_g1);
  569.   gsl_sf_lngamma_complex_e(0.25 - 0.5*mu, -0.5*tau, &ln_g2, &arg_g2);
  570.  
  571.   gsl_sf_exp_err_e(-2.0*ln_g1.val, 2.0*ln_g1.err, &pre1);
  572.   gsl_sf_exp_err_e(-2.0*ln_g2.val, 2.0*ln_g2.err, &pre2);
  573.   pre2.val *= -2.0*x;
  574.   pre2.err *=  2.0*fabs(x);
  575.   pre2.err +=  GSL_DBL_EPSILON * fabs(pre2.val);
  576.  
  577.   t1_val = pre1.val * F1.val;
  578.   t1_err = fabs(pre1.val) * F1.err + pre1.err * fabs(F1.val);
  579.   t2_val = pre2.val * F2.val;
  580.   t2_err = fabs(pre2.val) * F2.err + pre2.err * fabs(F2.val);
  581.  
  582.   result->val  = pre_val * (t1_val + t2_val);
  583.   result->err  = pre_val * (t1_err + t2_err);
  584.   result->err += pre_err * fabs(t1_val + t2_val);
  585.   result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  586.  
  587.   return status;
  588. }
  589.  
  590.  
  591. /* P^{mu}_{-1/2 + I tau}
  592.  * defining hypergeometric representation
  593.  * [Abramowitz+Stegun, 8.1.2]
  594.  * 1 < x < 3
  595.  * effective for x near 1
  596.  *
  597.  */
  598. #if 0
  599. static
  600. int
  601. conicalP_def_hyperg(double mu, double tau, double x, double * result)
  602. {
  603.   double F;
  604.   int stat_F = gsl_sf_hyperg_2F1_conj_renorm_e(0.5, tau, 1.0-mu, 0.5*(1.0-x), &F);
  605.   *result = pow((x+1.0)/(x-1.0), 0.5*mu) * F;
  606.   return stat_F;
  607. }
  608. #endif /* 0 */
  609.  
  610.  
  611. /* P^{mu}_{-1/2 + I tau}  second hypergeometric representation
  612.  * [Zhurina+Karmazina, (3.1)] 
  613.  * -1 < x < 3
  614.  * effective for x near 1
  615.  *
  616.  */
  617. #if 0
  618. static
  619. int
  620. conicalP_xnear1_hyperg_C(double mu, double tau, double x, double * result)
  621. {
  622.   double ln_pre, arg_pre;
  623.   double ln_g1, arg_g1;
  624.   double ln_g2, arg_g2;
  625.   double F;
  626.  
  627.   int stat_F = gsl_sf_hyperg_2F1_conj_renorm_e(0.5+mu, tau, 1.0+mu, 0.5*(1.0-x), &F);
  628.  
  629.   gsl_sf_lngamma_complex_e(0.5+mu, tau, &ln_g1, &arg_g1);
  630.   gsl_sf_lngamma_complex_e(0.5-mu, tau, &ln_g2, &arg_g2);
  631.  
  632.   ln_pre  = mu*M_LN2 - 0.5*mu*log(fabs(x*x-1.0)) + ln_g1 - ln_g2;
  633.   arg_pre = arg_g1 - arg_g2;
  634.  
  635.   *result = exp(ln_pre) * F;
  636.   return stat_F;
  637. }
  638. #endif /* 0 */
  639.  
  640.  
  641. /* V0, V1 from Kolbig, m = 0
  642.  */
  643. static
  644. int
  645. conicalP_0_V(const double t, const double f, const double tau, const double sgn,
  646.              double * V0, double * V1)
  647. {
  648.   double C[8];
  649.   double T[8];
  650.   double H[8];
  651.   double V[12];
  652.   int i;
  653.   T[0] = 1.0;
  654.   H[0] = 1.0;
  655.   V[0] = 1.0;
  656.   for(i=1; i<=7; i++) {
  657.     T[i] = T[i-1] * t;
  658.     H[i] = H[i-1] * (t*f);
  659.   }
  660.   for(i=1; i<=11; i++) {
  661.     V[i] = V[i-1] * tau;
  662.   }
  663.  
  664.   C[0] = 1.0;
  665.   C[1] = (H[1]-1.0)/(8.0*T[1]);
  666.   C[2] = (9.0*H[2] + 6.0*H[1] - 15.0 - sgn*8.0*T[2])/(128.0*T[2]);
  667.   C[3] = 5.0*(15.0*H[3] + 27.0*H[2] + 21.0*H[1] - 63.0 - sgn*T[2]*(16.0*H[1]+24.0))/(1024.0*T[3]);
  668.   C[4] = 7.0*(525.0*H[4] + 1500.0*H[3] + 2430.0*H[2] + 1980.0*H[1] - 6435.0
  669.               + 192.0*T[4] - sgn*T[2]*(720.0*H[2]+1600.0*H[1]+2160.0)
  670.               ) / (32768.0*T[4]);
  671.   C[5] = 21.0*(2835.0*H[5] + 11025.0*H[4] + 24750.0*H[3] + 38610.0*H[2]
  672.                + 32175.0*H[1] - 109395.0 + T[4]*(1984.0*H[1]+4032.0)
  673.                - sgn*T[2]*(4800.0*H[3]+15120.0*H[2]+26400.0*H[1]+34320.0)
  674.            ) / (262144.0*T[5]);
  675.   C[6] = 11.0*(218295.0*H[6] + 1071630.0*H[5] + 3009825.0*H[4] + 6142500.0*H[3]
  676.                + 9398025.0*H[2] + 7936110.0*H[1] - 27776385.0
  677.            + T[4]*(254016.0*H[2]+749952.0*H[1]+1100736.0)
  678.            - sgn*T[2]*(441000.0*H[4] + 1814400.0*H[3] + 4127760.0*H[2]
  679.                      + 6552000.0*H[1] + 8353800.0 + 31232.0*T[4]
  680.              )
  681.                ) / (4194304.0*T[6]);
  682.  
  683.   *V0 = C[0] + (-4.0*C[3]/T[1]+C[4])/V[4]
  684.              + (-192.0*C[5]/T[3]+144.0*C[6]/T[2])/V[8]
  685.              + sgn * (-C[2]/V[2]
  686.                   + (-24.0*C[4]/T[2]+12.0*C[5]/T[1]-C[6])/V[6] 
  687.                   + (-1920.0*C[6]/T[4])/V[10]
  688.               );
  689.   *V1 = C[1]/V[1] + (8.0*(C[3]/T[2]-C[4]/T[1])+C[5])/V[5]
  690.                   + (384.0*C[5]/T[4] - 768.0*C[6]/T[3])/V[9]
  691.                   + sgn * ((2.0*C[2]/T[1]-C[3])/V[3]
  692.                    + (48.0*C[4]/T[3]-72.0*C[5]/T[2] + 18.0*C[6]/T[1])/V[7]
  693.                    + (3840.0*C[6]/T[5])/V[11]
  694.                    );
  695.  
  696.   return GSL_SUCCESS;
  697. }
  698.  
  699.  
  700. /* V0, V1 from Kolbig, m = 1
  701.  */
  702. static
  703. int
  704. conicalP_1_V(const double t, const double f, const double tau, const double sgn,
  705.              double * V0, double * V1)
  706. {
  707.   double Cm1;
  708.   double C[8];
  709.   double T[8];
  710.   double H[8];
  711.   double V[12];
  712.   int i;
  713.   T[0] = 1.0;
  714.   H[0] = 1.0;
  715.   V[0] = 1.0;
  716.   for(i=1; i<=7; i++) {
  717.     T[i] = T[i-1] * t;
  718.     H[i] = H[i-1] * (t*f);
  719.   }
  720.   for(i=1; i<=11; i++) {
  721.     V[i] = V[i-1] * tau;
  722.   }
  723.  
  724.   Cm1  = -1.0;
  725.   C[0] = 3.0*(1.0-H[1])/(8.0*T[1]);
  726.   C[1] = (-15.0*H[2]+6.0*H[1]+9.0+sgn*8.0*T[2])/(128.0*T[2]);
  727.   C[2] = 3.0*(-35.0*H[3] - 15.0*H[2] + 15.0*H[1] + 35.0 + sgn*T[2]*(32.0*H[1]+8.0))/(1024.0*T[3]);
  728.   C[3] = (-4725.0*H[4] - 6300.0*H[3] - 3150.0*H[2] + 3780.0*H[1] + 10395.0
  729.           -1216.0*T[4] + sgn*T[2]*(6000.0*H[2]+5760.0*H[1]+1680.0)) / (32768.0*T[4]);
  730.   C[4] = 7.0*(-10395.0*H[5] - 23625.0*H[4] - 28350.0*H[3] - 14850.0*H[2]
  731.               +19305.0*H[1] + 57915.0 - T[4]*(6336.0*H[1]+6080.0)
  732.           + sgn*T[2]*(16800.0*H[3] + 30000.0*H[2] + 25920.0*H[1] + 7920.0)
  733.           ) / (262144.0*T[5]);
  734.   C[5] = (-2837835.0*H[6] - 9168390.0*H[5] - 16372125.0*H[4] - 18918900*H[3]
  735.           -10135125.0*H[2] + 13783770.0*H[1] + 43648605.0
  736.       -T[4]*(3044160.0*H[2] + 5588352.0*H[1] + 4213440.0)
  737.       +sgn*T[2]*(5556600.0*H[4] + 14817600.0*H[3] + 20790000.0*H[2]
  738.                  + 17297280.0*H[1] + 5405400.0 + 323072.0*T[4]
  739.              )
  740.           ) / (4194304.0*T[6]);
  741.   C[6] = 0.0;
  742.  
  743.   *V0 = C[0] + (-4.0*C[3]/T[1]+C[4])/V[4]
  744.              + (-192.0*C[5]/T[3]+144.0*C[6]/T[2])/V[8]
  745.              + sgn * (-C[2]/V[2]
  746.                   + (-24.0*C[4]/T[2]+12.0*C[5]/T[1]-C[6])/V[6] 
  747.               );
  748.   *V1 = C[1]/V[1] + (8.0*(C[3]/T[2]-C[4]/T[1])+C[5])/V[5]
  749.                   + (384.0*C[5]/T[4] - 768.0*C[6]/T[3])/V[9]
  750.                   + sgn * (Cm1*V[1] + (2.0*C[2]/T[1]-C[3])/V[3]
  751.                    + (48.0*C[4]/T[3]-72.0*C[5]/T[2] + 18.0*C[6]/T[1])/V[7]
  752.                    );
  753.  
  754.   return GSL_SUCCESS;
  755. }
  756.  
  757.  
  758.  
  759. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  760.  
  761. /* P^0_{-1/2 + I lambda}
  762.  */
  763. int
  764. gsl_sf_conicalP_0_e(const double lambda, const double x, gsl_sf_result * result)
  765. {
  766.   /* CHECK_POINTER(result) */
  767.  
  768.   if(x <= -1.0) {
  769.     DOMAIN_ERROR(result);
  770.   }
  771.   else if(x == 1.0) {
  772.     result->val = 1.0;
  773.     result->err = 0.0;
  774.     return GSL_SUCCESS;
  775.   }
  776.   else if(lambda == 0.0) {
  777.     gsl_sf_result K;
  778.     int stat_K;
  779.     if(x < 1.0) {
  780.       const double th = acos(x);
  781.       const double s  = sin(0.5*th);
  782.       stat_K = gsl_sf_ellint_Kcomp_e(s, GSL_MODE_DEFAULT, &K);
  783.       result->val  = 2.0/M_PI * K.val;
  784.       result->err  = 2.0/M_PI * K.err;
  785.       result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  786.       return stat_K;
  787.     }
  788.     else {
  789.       const double xi = acosh(x);
  790.       const double c  = cosh(0.5*xi);
  791.       const double t  = tanh(0.5*xi);
  792.       stat_K = gsl_sf_ellint_Kcomp_e(t, GSL_MODE_DEFAULT, &K);
  793.       result->val  = 2.0/M_PI / c * K.val;
  794.       result->err  = 2.0/M_PI / c * K.err;
  795.       result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  796.       return stat_K;
  797.     }
  798.   }
  799.   else if(   (x <= 0.0 && lambda < 1000.0)
  800.           || (x <  0.1 && lambda < 17.0)
  801.       || (x <  0.2 && lambda < 5.0 )
  802.     ) {
  803.     return conicalP_xlt1_hyperg_A(0.0, lambda, x, result);
  804.   }
  805.   else if(   (x <= 0.2 && lambda < 17.0)
  806.           || (x <= 1.5 && lambda < 20.0)
  807.     ) {
  808.     return gsl_sf_hyperg_2F1_conj_e(0.5, lambda, 1.0, (1.0-x)/2, result);
  809.   }
  810.   else if(1.5 < x && lambda < GSL_MAX(x,20.0)) {
  811.     gsl_sf_result P;
  812.     double lm;
  813.     int stat_P = gsl_sf_conicalP_large_x_e(0.0, lambda, x,
  814.                                               &P, &lm
  815.                                               );
  816.     int stat_e = gsl_sf_exp_mult_err_e(lm, 2.0*GSL_DBL_EPSILON * fabs(lm),
  817.                           P.val, P.err,
  818.                           result);
  819.     return GSL_ERROR_SELECT_2(stat_e, stat_P);
  820.   }
  821.   else {
  822.     double V0, V1;
  823.     if(x < 1.0) {
  824.       double th  = acos(x);
  825.       double sth = sqrt(1.0-x*x);  /* sin(th) */
  826.       gsl_sf_result I0, I1;
  827.       int stat_I0 = gsl_sf_bessel_I0_scaled_e(th * lambda, &I0);
  828.       int stat_I1 = gsl_sf_bessel_I1_scaled_e(th * lambda, &I1);
  829.       int stat_I  = GSL_ERROR_SELECT_2(stat_I0, stat_I1);
  830.       int stat_V  = conicalP_0_V(th, x/sth, lambda, -1.0, &V0, &V1);
  831.       double bessterm = V0 * I0.val + V1 * I1.val;
  832.       double besserr  = fabs(V0) * I0.err + fabs(V1) * I1.err;
  833.       double arg1 = th*lambda;
  834.       double sqts = sqrt(th/sth);
  835.       int stat_e = gsl_sf_exp_mult_err_e(arg1, 4.0 * GSL_DBL_EPSILON * fabs(arg1),
  836.                                             sqts * bessterm, sqts * besserr,
  837.                         result);
  838.       return GSL_ERROR_SELECT_3(stat_e, stat_V, stat_I);
  839.     }
  840.     else {
  841.       double sh = sqrt(x-1.0)*sqrt(x+1.0);  /* sinh(xi)      */
  842.       double xi = log(x + sh);              /* xi = acosh(x) */
  843.       gsl_sf_result J0, J1;
  844.       int stat_J0 = gsl_sf_bessel_J0_e(xi * lambda, &J0);
  845.       int stat_J1 = gsl_sf_bessel_J1_e(xi * lambda, &J1);
  846.       int stat_J  = GSL_ERROR_SELECT_2(stat_J0, stat_J1);
  847.       int stat_V  = conicalP_0_V(xi, x/sh, lambda, 1.0, &V0, &V1);
  848.       double bessterm = V0 * J0.val + V1 * J1.val;
  849.       double besserr  = fabs(V0) * J0.err + fabs(V1) * J1.err;
  850.       double pre_val = sqrt(xi/sh);
  851.       double pre_err = 2.0 * fabs(pre_val);
  852.       result->val  = pre_val * bessterm;
  853.       result->err  = pre_val * besserr;
  854.       result->err += pre_err * fabs(bessterm);
  855.       result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  856.       return GSL_ERROR_SELECT_2(stat_V, stat_J);
  857.     }
  858.   }
  859. }
  860.  
  861.  
  862. /* P^1_{-1/2 + I lambda}
  863.  */
  864. int
  865. gsl_sf_conicalP_1_e(const double lambda, const double x, gsl_sf_result * result)
  866. {
  867.   /* CHECK_POINTER(result) */
  868.  
  869.   if(x <= -1.0) {
  870.     DOMAIN_ERROR(result);
  871.   }
  872.   else if(lambda == 0.0) {
  873.     gsl_sf_result K, E;
  874.     int stat_K, stat_E;
  875.     if(x == 1.0) {
  876.       result->val = 0.0;
  877.       result->err = 0.0;
  878.       return GSL_SUCCESS;
  879.     }
  880.     else if(x < 1.0) {
  881.       if(1.0-x < GSL_SQRT_DBL_EPSILON) {
  882.         double err_amp = GSL_MAX_DBL(1.0, 1.0/(GSL_DBL_EPSILON + fabs(1.0-x)));
  883.         result->val = 0.25/M_SQRT2 * sqrt(1.0-x) * (1.0 + 5.0/16.0 * (1.0-x));
  884.     result->err = err_amp * 3.0 * GSL_DBL_EPSILON * fabs(result->val);
  885.     return GSL_SUCCESS;
  886.       }
  887.       else {
  888.         const double th = acos(x);
  889.         const double s  = sin(0.5*th);
  890.         const double c2 = 1.0 - s*s;
  891.         const double sth = sin(th);
  892.     const double pre = 2.0/(M_PI*sth);
  893.         stat_K = gsl_sf_ellint_Kcomp_e(s, GSL_MODE_DEFAULT, &K);
  894.         stat_E = gsl_sf_ellint_Ecomp_e(s, GSL_MODE_DEFAULT, &E);
  895.         result->val  = pre * (E.val - c2 * K.val);
  896.     result->err  = pre * (E.err + fabs(c2) * K.err);
  897.     result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  898.         return stat_K;
  899.       }
  900.     }
  901.     else {
  902.       if(x-1.0 < GSL_SQRT_DBL_EPSILON) {
  903.         double err_amp = GSL_MAX_DBL(1.0, 1.0/(GSL_DBL_EPSILON + fabs(1.0-x)));
  904.         result->val = -0.25/M_SQRT2 * sqrt(x-1.0) * (1.0 - 5.0/16.0 * (x-1.0));
  905.     result->err = err_amp * 3.0 * GSL_DBL_EPSILON * fabs(result->val);
  906.     return GSL_SUCCESS;
  907.       }
  908.       else {
  909.         const double xi = acosh(x);
  910.         const double c  = cosh(0.5*xi);
  911.         const double t  = tanh(0.5*xi);
  912.         const double sxi = sinh(xi);
  913.     const double pre = 2.0/(M_PI*sxi) * c;
  914.         stat_K = gsl_sf_ellint_Kcomp_e(t, GSL_MODE_DEFAULT, &K);
  915.         stat_E = gsl_sf_ellint_Ecomp_e(t, GSL_MODE_DEFAULT, &E);
  916.         result->val  = pre * (E.val - K.val);
  917.     result->err  = pre * (E.err + K.err);
  918.     result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  919.         return stat_K;
  920.       }
  921.     }
  922.   }
  923.   else if(   (x <= 0.0 && lambda < 1000.0)
  924.           || (x <  0.1 && lambda < 17.0)
  925.       || (x <  0.2 && lambda < 5.0 )
  926.     ) {
  927.     return conicalP_xlt1_hyperg_A(1.0, lambda, x, result);
  928.   }
  929.   else if(   (x <= 0.2 && lambda < 17.0)
  930.           || (x <  1.5 && lambda < 20.0)
  931.     ) {
  932.     const double arg = fabs(x*x - 1.0);
  933.     const double sgn = GSL_SIGN(1.0 - x);
  934.     const double pre = 0.5*(lambda*lambda + 0.25) * sgn * sqrt(arg);
  935.     gsl_sf_result F;
  936.     int stat_F = gsl_sf_hyperg_2F1_conj_e(1.5, lambda, 2.0, (1.0-x)/2, &F);
  937.     result->val  = pre * F.val;
  938.     result->err  = fabs(pre) * F.err;
  939.     result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  940.     return stat_F;
  941.   }
  942.   else if(1.5 <= x && lambda < GSL_MAX(x,20.0)) {
  943.     gsl_sf_result P;
  944.     double lm;
  945.     int stat_P = gsl_sf_conicalP_large_x_e(1.0, lambda, x,
  946.                                               &P, &lm
  947.                                               );
  948.     int stat_e = gsl_sf_exp_mult_err_e(lm, 2.0 * GSL_DBL_EPSILON * fabs(lm),
  949.                           P.val, P.err,
  950.                           result);
  951.     return GSL_ERROR_SELECT_2(stat_e, stat_P);
  952.   }
  953.   else {
  954.     double V0, V1;
  955.     if(x < 1.0) {
  956.       const double sqrt_1mx = sqrt(1.0 - x);
  957.       const double sqrt_1px = sqrt(1.0 + x);
  958.       const double th  = acos(x);
  959.       const double sth = sqrt_1mx * sqrt_1px;  /* sin(th) */
  960.       gsl_sf_result I0, I1;
  961.       int stat_I0 = gsl_sf_bessel_I0_scaled_e(th * lambda, &I0);
  962.       int stat_I1 = gsl_sf_bessel_I1_scaled_e(th * lambda, &I1);
  963.       int stat_I  = GSL_ERROR_SELECT_2(stat_I0, stat_I1);
  964.       int stat_V  = conicalP_1_V(th, x/sth, lambda, -1.0, &V0, &V1);
  965.       double bessterm = V0 * I0.val + V1 * I1.val;
  966.       double besserr  =  fabs(V0) * I0.err + fabs(V1) * I1.err
  967.                        + 2.0 * GSL_DBL_EPSILON * fabs(V0 * I0.val)
  968.                + 2.0 * GSL_DBL_EPSILON * fabs(V1 * I1.val);
  969.       double arg1 = th * lambda;
  970.       double sqts = sqrt(th/sth);
  971.       int stat_e = gsl_sf_exp_mult_err_e(arg1, 2.0 * GSL_DBL_EPSILON * fabs(arg1),
  972.                                             sqts * bessterm, sqts * besserr,
  973.                         result);
  974.       result->err *= 1.0/sqrt_1mx;
  975.       return GSL_ERROR_SELECT_3(stat_e, stat_V, stat_I);
  976.     }
  977.     else {
  978.       const double sqrt_xm1 = sqrt(x - 1.0);
  979.       const double sqrt_xp1 = sqrt(x + 1.0);
  980.       const double sh = sqrt_xm1 * sqrt_xp1;  /* sinh(xi)      */
  981.       const double xi = log(x + sh);          /* xi = acosh(x) */
  982.       const double xi_lam = xi * lambda;
  983.       gsl_sf_result J0, J1;
  984.       const int stat_J0 = gsl_sf_bessel_J0_e(xi_lam, &J0);
  985.       const int stat_J1 = gsl_sf_bessel_J1_e(xi_lam, &J1);
  986.       const int stat_J  = GSL_ERROR_SELECT_2(stat_J0, stat_J1);
  987.       const int stat_V  = conicalP_1_V(xi, x/sh, lambda, 1.0, &V0, &V1);
  988.       const double bessterm = V0 * J0.val + V1 * J1.val;
  989.       const double besserr  = fabs(V0) * J0.err + fabs(V1) * J1.err
  990.                        + 512.0 * 2.0 * GSL_DBL_EPSILON * fabs(V0 * J0.val)
  991.                + 512.0 * 2.0 * GSL_DBL_EPSILON * fabs(V1 * J1.val)
  992.                        + GSL_DBL_EPSILON * fabs(xi_lam * V0 * J1.val)
  993.                        + GSL_DBL_EPSILON * fabs(xi_lam * V1 * J0.val);
  994.       const double pre = sqrt(xi/sh);
  995.       result->val  = pre * bessterm;
  996.       result->err  = pre * besserr * sqrt_xp1 / sqrt_xm1;
  997.       result->err += 4.0 * GSL_DBL_EPSILON * fabs(result->val);
  998.       return GSL_ERROR_SELECT_2(stat_V, stat_J);
  999.     }
  1000.   }
  1001. }
  1002.  
  1003.  
  1004. /* P^{1/2}_{-1/2 + I lambda} (x)
  1005.  * [Abramowitz+Stegun 8.6.8, 8.6.12]
  1006.  * checked OK [GJ] Fri May  8 12:24:36 MDT 1998 
  1007.  */
  1008. int gsl_sf_conicalP_half_e(const double lambda, const double x,
  1009.                               gsl_sf_result * result
  1010.                               )
  1011. {
  1012.   /* CHECK_POINTER(result) */
  1013.  
  1014.   if(x <= -1.0) {
  1015.     DOMAIN_ERROR(result);
  1016.   }
  1017.   else if(x < 1.0) {
  1018.     double err_amp = 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-fabs(x)));
  1019.     double ac  = acos(x);
  1020.     double den = sqrt(sqrt(1.0-x)*sqrt(1.0+x));
  1021.     result->val  = Root_2OverPi_ / den * cosh(ac * lambda);
  1022.     result->err  = err_amp * 3.0 * GSL_DBL_EPSILON * fabs(result->val);
  1023.     result->err *= fabs(ac * lambda) + 1.0;
  1024.     return GSL_SUCCESS;
  1025.   }
  1026.   else if(x == 1.0) {
  1027.     result->val = 0.0;
  1028.     result->err = 0.0;
  1029.     return GSL_SUCCESS;
  1030.   }
  1031.   else {
  1032.     /* x > 1 */
  1033.     double err_amp = 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-fabs(x)));
  1034.     double sq_term = sqrt(x-1.0)*sqrt(x+1.0);
  1035.     double ln_term = log(x + sq_term);
  1036.     double den = sqrt(sq_term);
  1037.     double carg_val = lambda * ln_term;
  1038.     double carg_err = 2.0 * GSL_DBL_EPSILON * fabs(carg_val);
  1039.     gsl_sf_result cos_result;
  1040.     int stat_cos = gsl_sf_cos_err_e(carg_val, carg_err, &cos_result);
  1041.     result->val  = Root_2OverPi_ / den * cos_result.val;
  1042.     result->err  = err_amp * Root_2OverPi_ / den * cos_result.err;
  1043.     result->err += 4.0 * GSL_DBL_EPSILON * fabs(result->val);
  1044.     return stat_cos;
  1045.   }
  1046. }
  1047.  
  1048.  
  1049. /* P^{-1/2}_{-1/2 + I lambda} (x)
  1050.  * [Abramowitz+Stegun 8.6.9, 8.6.14]
  1051.  * checked OK [GJ] Fri May  8 12:24:43 MDT 1998 
  1052.  */
  1053. int gsl_sf_conicalP_mhalf_e(const double lambda, const double x, gsl_sf_result * result)
  1054. {
  1055.   /* CHECK_POINTER(result) */
  1056.  
  1057.   if(x <= -1.0) {
  1058.     DOMAIN_ERROR(result);
  1059.   }
  1060.   else if(x < 1.0) {
  1061.     double ac  = acos(x);
  1062.     double den = sqrt(sqrt(1.0-x)*sqrt(1.0+x));
  1063.     double arg = ac * lambda;
  1064.     double err_amp = 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-fabs(x)));
  1065.     if(fabs(arg) < GSL_SQRT_DBL_EPSILON) {
  1066.       result->val  = Root_2OverPi_ / den * ac;
  1067.       result->err  = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1068.       result->err *= err_amp;
  1069.     }
  1070.     else {
  1071.       result->val  = Root_2OverPi_ / (den*lambda) * sinh(arg);
  1072.       result->err  = GSL_DBL_EPSILON * (fabs(arg)+1.0) * fabs(result->val);
  1073.       result->err *= err_amp;
  1074.       result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1075.     }
  1076.     return GSL_SUCCESS;
  1077.   }
  1078.   else if(x == 1.0) {
  1079.     result->val = 0.0;
  1080.     result->err = 0.0;
  1081.     return GSL_SUCCESS;
  1082.   }
  1083.   else {
  1084.     /* x > 1 */
  1085.     double sq_term = sqrt(x-1.0)*sqrt(x+1.0);
  1086.     double ln_term = log(x + sq_term);
  1087.     double den = sqrt(sq_term);
  1088.     double arg_val = lambda * ln_term;
  1089.     double arg_err = 2.0 * GSL_DBL_EPSILON * fabs(arg_val);
  1090.     if(arg_val < GSL_SQRT_DBL_EPSILON) {
  1091.       result->val = Root_2OverPi_ / den * ln_term;
  1092.       result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1093.       return GSL_SUCCESS;
  1094.     }
  1095.     else {
  1096.       gsl_sf_result sin_result;
  1097.       int stat_sin = gsl_sf_sin_err_e(arg_val, arg_err, &sin_result);
  1098.       result->val  = Root_2OverPi_ / (den*lambda) * sin_result.val;
  1099.       result->err  = Root_2OverPi_ / fabs(den*lambda) * sin_result.err;
  1100.       result->err += 3.0 * GSL_DBL_EPSILON * fabs(result->val);
  1101.       return stat_sin;
  1102.     }
  1103.   }
  1104. }
  1105.  
  1106.  
  1107. int gsl_sf_conicalP_sph_reg_e(const int l, const double lambda,
  1108.                                  const double x,
  1109.                                  gsl_sf_result * result
  1110.                                  )
  1111. {
  1112.   /* CHECK_POINTER(result) */
  1113.  
  1114.   if(x <= -1.0 || l < -1) {
  1115.     DOMAIN_ERROR(result);
  1116.   }
  1117.   else if(l == -1) {
  1118.     return gsl_sf_conicalP_half_e(lambda, x, result);
  1119.   }
  1120.   else if(l == 0) {
  1121.     return gsl_sf_conicalP_mhalf_e(lambda, x, result);
  1122.   }
  1123.   else if(x == 1.0) {
  1124.     result->val = 0.0;
  1125.     result->err = 0.0;
  1126.     return GSL_SUCCESS;
  1127.   }
  1128.   else if(x < 0.0) {
  1129.     double c = 1.0/sqrt(1.0-x*x);
  1130.     gsl_sf_result r_Pellm1;
  1131.     gsl_sf_result r_Pell;
  1132.     int stat_0 = gsl_sf_conicalP_half_e(lambda, x, &r_Pellm1);  /* P^( 1/2) */
  1133.     int stat_1 = gsl_sf_conicalP_mhalf_e(lambda, x, &r_Pell);   /* P^(-1/2) */
  1134.     int stat_P = GSL_ERROR_SELECT_2(stat_0, stat_1);
  1135.     double Pellm1 = r_Pellm1.val;
  1136.     double Pell   = r_Pell.val;
  1137.     double Pellp1;
  1138.     int ell;
  1139.  
  1140.     for(ell=0; ell<l; ell++) {
  1141.       double d = (ell+1.0)*(ell+1.0) + lambda*lambda;
  1142.       Pellp1 = (Pellm1 - (2.0*ell+1.0)*c*x * Pell) / d;
  1143.       Pellm1 = Pell;
  1144.       Pell   = Pellp1;
  1145.     }
  1146.  
  1147.     result->val  = Pell;
  1148.     result->err  = (0.5*l + 1.0) * GSL_DBL_EPSILON * fabs(Pell);
  1149.     result->err += GSL_DBL_EPSILON * l * fabs(result->val);
  1150.     return stat_P;
  1151.   }
  1152.   else if(x < 1.0) {
  1153.     const double xi = x/(sqrt(1.0-x)*sqrt(1.0+x));
  1154.     gsl_sf_result rat;
  1155.     gsl_sf_result Phf;
  1156.     int stat_CF1 = conicalP_negmu_xlt1_CF1(0.5, l, lambda, x, &rat);
  1157.     int stat_Phf = gsl_sf_conicalP_half_e(lambda, x, &Phf);
  1158.     double Pellp1 = rat.val * GSL_SQRT_DBL_MIN;
  1159.     double Pell   = GSL_SQRT_DBL_MIN;
  1160.     double Pellm1;
  1161.     int ell;
  1162.  
  1163.     for(ell=l; ell>=0; ell--) {
  1164.       double d = (ell+1.0)*(ell+1.0) + lambda*lambda;
  1165.       Pellm1 = (2.0*ell+1.0)*xi * Pell + d * Pellp1;
  1166.       Pellp1 = Pell;
  1167.       Pell   = Pellm1;
  1168.     }
  1169.  
  1170.     result->val  = GSL_SQRT_DBL_MIN * Phf.val / Pell;
  1171.     result->err  = GSL_SQRT_DBL_MIN * Phf.err / fabs(Pell);
  1172.     result->err += fabs(rat.err/rat.val) * (l + 1.0) * fabs(result->val);
  1173.     result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1174.  
  1175.     return GSL_ERROR_SELECT_2(stat_Phf, stat_CF1);
  1176.   }
  1177.   else if(x == 1.0) {
  1178.     result->val = 0.0;
  1179.     result->err = 0.0;
  1180.     return GSL_SUCCESS;
  1181.   }
  1182.   else {
  1183.     /* x > 1.0 */
  1184.  
  1185.     const double xi = x/sqrt((x-1.0)*(x+1.0));
  1186.     gsl_sf_result rat;
  1187.     int stat_CF1 = conicalP_negmu_xgt1_CF1(0.5, l, lambda, x, &rat);
  1188.     int stat_P;
  1189.     double Pellp1 = rat.val * GSL_SQRT_DBL_MIN;
  1190.     double Pell   = GSL_SQRT_DBL_MIN;
  1191.     double Pellm1;
  1192.     int ell;
  1193.  
  1194.     for(ell=l; ell>=0; ell--) {
  1195.       double d = (ell+1.0)*(ell+1.0) + lambda*lambda;
  1196.       Pellm1 = (2.0*ell+1.0)*xi * Pell - d * Pellp1;
  1197.       Pellp1 = Pell;
  1198.       Pell   = Pellm1;
  1199.     }
  1200.  
  1201.     if(fabs(Pell) > fabs(Pellp1)){
  1202.       gsl_sf_result Phf;
  1203.       stat_P = gsl_sf_conicalP_half_e(lambda, x, &Phf);
  1204.       result->val  =       GSL_SQRT_DBL_MIN * Phf.val / Pell;
  1205.       result->err  = 2.0 * GSL_SQRT_DBL_MIN * Phf.err / fabs(Pell);
  1206.       result->err += 2.0 * fabs(rat.err/rat.val) * (l + 1.0) * fabs(result->val);
  1207.       result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1208.     }
  1209.     else {
  1210.       gsl_sf_result Pmhf;
  1211.       stat_P = gsl_sf_conicalP_mhalf_e(lambda, x, &Pmhf);
  1212.       result->val  =       GSL_SQRT_DBL_MIN * Pmhf.val / Pellp1;
  1213.       result->err  = 2.0 * GSL_SQRT_DBL_MIN * Pmhf.err / fabs(Pellp1);
  1214.       result->err += 2.0 * fabs(rat.err/rat.val) * (l + 1.0) * fabs(result->val);
  1215.       result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1216.     }
  1217.  
  1218.     return GSL_ERROR_SELECT_2(stat_P, stat_CF1);
  1219.   }
  1220. }
  1221.  
  1222.  
  1223. int gsl_sf_conicalP_cyl_reg_e(const int m, const double lambda,
  1224.                                  const double x,
  1225.                                  gsl_sf_result * result
  1226.                                  )
  1227. {
  1228.   /* CHECK_POINTER(result) */
  1229.  
  1230.   if(x <= -1.0 || m < -1) {
  1231.     DOMAIN_ERROR(result);
  1232.   }
  1233.   else if(m == -1) {
  1234.     return gsl_sf_conicalP_1_e(lambda, x, result);
  1235.   }
  1236.   else if(m == 0) {
  1237.     return gsl_sf_conicalP_0_e(lambda, x, result);
  1238.   }
  1239.   else if(x == 1.0) {
  1240.     result->val = 0.0;
  1241.     result->err = 0.0;
  1242.     return GSL_SUCCESS;
  1243.   }
  1244.   else if(x < 0.0) {
  1245.     double c = 1.0/sqrt(1.0-x*x);
  1246.     gsl_sf_result r_Pkm1;
  1247.     gsl_sf_result r_Pk;
  1248.     int stat_0 = gsl_sf_conicalP_1_e(lambda, x, &r_Pkm1);  /* P^1 */
  1249.     int stat_1 = gsl_sf_conicalP_0_e(lambda, x, &r_Pk);    /* P^0 */
  1250.     int stat_P = GSL_ERROR_SELECT_2(stat_0, stat_1);
  1251.     double Pkm1 = r_Pkm1.val;
  1252.     double Pk   = r_Pk.val;
  1253.     double Pkp1;
  1254.     int k;
  1255.  
  1256.     for(k=0; k<m; k++) {
  1257.       double d = (k+0.5)*(k+0.5) + lambda*lambda;
  1258.       Pkp1 = (Pkm1 - 2.0*k*c*x * Pk) / d;
  1259.       Pkm1 = Pk;
  1260.       Pk   = Pkp1;
  1261.     }
  1262.  
  1263.     result->val  = Pk;
  1264.     result->err  = (m + 2.0) * GSL_DBL_EPSILON * fabs(Pk);
  1265.     result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1266.  
  1267.     return stat_P;
  1268.   }
  1269.   else if(x < 1.0) {
  1270.     const double xi = x/(sqrt(1.0-x)*sqrt(1.0+x));
  1271.     gsl_sf_result rat;
  1272.     gsl_sf_result P0;
  1273.     int stat_CF1 = conicalP_negmu_xlt1_CF1(0.0, m, lambda, x, &rat);
  1274.     int stat_P0  = gsl_sf_conicalP_0_e(lambda, x, &P0);
  1275.     double Pkp1 = rat.val * GSL_SQRT_DBL_MIN;
  1276.     double Pk   = GSL_SQRT_DBL_MIN;
  1277.     double Pkm1;
  1278.     int k;
  1279.  
  1280.     for(k=m; k>0; k--) {
  1281.       double d = (k+0.5)*(k+0.5) + lambda*lambda;
  1282.       Pkm1 = 2.0*k*xi * Pk + d * Pkp1;
  1283.       Pkp1 = Pk;
  1284.       Pk   = Pkm1;
  1285.     }
  1286.  
  1287.     result->val  = GSL_SQRT_DBL_MIN * P0.val / Pk;
  1288.     result->err  = 2.0 * GSL_SQRT_DBL_MIN * P0.err / fabs(Pk);
  1289.     result->err += 2.0 * fabs(rat.err/rat.val) * (m + 1.0) * fabs(result->val);
  1290.     result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1291.  
  1292.     return GSL_ERROR_SELECT_2(stat_P0, stat_CF1);
  1293.   }
  1294.   else if(x == 1.0) {
  1295.     result->val = 0.0;
  1296.     result->err = 0.0;
  1297.     return GSL_SUCCESS;
  1298.   }
  1299.   else {
  1300.     /* x > 1.0 */
  1301.  
  1302.     const double xi = x/sqrt((x-1.0)*(x+1.0));
  1303.     gsl_sf_result rat;
  1304.     int stat_CF1 = conicalP_negmu_xgt1_CF1(0.0, m, lambda, x, &rat);
  1305.     int stat_P;
  1306.     double Pkp1 = rat.val * GSL_SQRT_DBL_MIN;
  1307.     double Pk   = GSL_SQRT_DBL_MIN;
  1308.     double Pkm1;
  1309.     int k;
  1310.  
  1311.     for(k=m; k>-1; k--) {
  1312.       double d = (k+0.5)*(k+0.5) + lambda*lambda;
  1313.       Pkm1 = 2.0*k*xi * Pk - d * Pkp1;
  1314.       Pkp1 = Pk;
  1315.       Pk   = Pkm1;
  1316.     }
  1317.  
  1318.     if(fabs(Pk) > fabs(Pkp1)){
  1319.       gsl_sf_result P1;
  1320.       stat_P = gsl_sf_conicalP_1_e(lambda, x, &P1);
  1321.       result->val  = GSL_SQRT_DBL_MIN * P1.val / Pk;
  1322.       result->err  = 2.0 * GSL_SQRT_DBL_MIN * P1.err / fabs(Pk);
  1323.       result->err += 2.0 * fabs(rat.err/rat.val) * (m+2.0) * fabs(result->val);
  1324.       result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1325.     }
  1326.     else {
  1327.       gsl_sf_result P0;
  1328.       stat_P = gsl_sf_conicalP_0_e(lambda, x, &P0);
  1329.       result->val  = GSL_SQRT_DBL_MIN * P0.val / Pkp1;
  1330.       result->err  = 2.0 * GSL_SQRT_DBL_MIN * P0.err / fabs(Pkp1);
  1331.       result->err += 2.0 * fabs(rat.err/rat.val) * (m+2.0) * fabs(result->val);
  1332.       result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1333.     }
  1334.  
  1335.     return GSL_ERROR_SELECT_2(stat_P, stat_CF1);
  1336.   }
  1337. }
  1338.  
  1339.  
  1340. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  1341.  
  1342. #include "eval.h"
  1343.  
  1344. double gsl_sf_conicalP_0(const double lambda, const double x)
  1345. {
  1346.   EVAL_RESULT(gsl_sf_conicalP_0_e(lambda, x, &result));
  1347. }
  1348.  
  1349. double gsl_sf_conicalP_1(const double lambda, const double x)
  1350. {
  1351.   EVAL_RESULT(gsl_sf_conicalP_1_e(lambda, x, &result));
  1352. }
  1353.  
  1354. double gsl_sf_conicalP_half(const double lambda, const double x)
  1355. {
  1356.   EVAL_RESULT(gsl_sf_conicalP_half_e(lambda, x, &result));
  1357. }
  1358.  
  1359. double gsl_sf_conicalP_mhalf(const double lambda, const double x)
  1360. {
  1361.   EVAL_RESULT(gsl_sf_conicalP_mhalf_e(lambda, x, &result));
  1362. }
  1363.  
  1364. double gsl_sf_conicalP_sph_reg(const int l, const double lambda, const double x)
  1365. {
  1366.   EVAL_RESULT(gsl_sf_conicalP_sph_reg_e(l, lambda, x, &result));
  1367. }
  1368.  
  1369. double gsl_sf_conicalP_cyl_reg(const int m, const double lambda, const double x)
  1370. {
  1371.   EVAL_RESULT(gsl_sf_conicalP_cyl_reg_e(m, lambda, x, &result));
  1372. }
  1373.